package thread;

//sleep与wait方法在锁上的区别

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.SynchronousQueue;

public class Test16_sleep_wait_lock {
    /**
     * 此方法会被n个线程来调用，会发生争抢，同时只能一个线程进行执行
     * sleep方法不会释放锁，因此线程按照先后顺序执行
     * synchronized的作用：加锁
     */
    public void run(){

    }
    public synchronized  void sleepMethod(){//Test16_sleep_wait_lock的对象锁
        System.out.println(printDate()+Thread.currentThread().getName()+"休眠1s");
        try {
            Thread.sleep(1000);//不会释放锁
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println(printDate()+Thread.currentThread().getName()+"休眠结束");
    }
    /**
     * wait方法会释放锁，因此一旦调用wait方法就会造成其他线程运行
     * 同步方法
     */
    public void waitMethod(){//TODO:  public synchronized void waitMethod()
        System.out.println(printDate()+Thread.currentThread().getName()+"等待1s");
        synchronized (this){//细粒度 同步块
            try {
                this.wait(1000);//释放锁
            }catch (InterruptedException e){
                e.printStackTrace();
            }
        }
        System.out.println(printDate()+Thread.currentThread().getName()+"等待结束");
    }

    public static void main(String[] args) {
        final Test16_sleep_wait_lock test = new Test16_sleep_wait_lock();
        for (int i=0;i<5;i++){
            /**
             * 不推荐之间创建线程
             * 推荐使用线程池管理线程
             */
            new Thread(test::sleepMethod).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    test.sleepMethod();
                }
            }).start();
        }

        //测试另一种情况wait
        System.out.println("---------------------");
        final Test16_sleep_wait_lock test1 = new Test16_sleep_wait_lock();
        for (int i=0;i<5;i++){
            new Thread(test1::sleepMethod).start();
        }
    }
    private static String printDate(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDateFormat.format(new Date())+" ";
    }
}
